home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / manage / snmp / cmu-snmp1.0 / snmplib / snmp_vars.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-19  |  33.1 KB  |  891 lines

  1. /*
  2.  * snmp_vars.c - return a pointer to the named variable.
  3.  *
  4.  *
  5.  */
  6. /***********************************************************
  7.     Copyright 1988, 1989 by Carnegie Mellon University
  8.  
  9.                       All Rights Reserved
  10.  
  11. Permission to use, copy, modify, and distribute this software and its 
  12. documentation for any purpose and without fee is hereby granted, 
  13. provided that the above copyright notice appear in all copies and that
  14. both that copyright notice and this permission notice appear in 
  15. supporting documentation, and that the name of CMU not be
  16. used in advertising or publicity pertaining to distribution of the
  17. software without specific, written prior permission.  
  18.  
  19. CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  20. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  21. CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  22. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  23. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  24. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  25. SOFTWARE.
  26. ******************************************************************/
  27. #ifdef KINETICS
  28. #include "gw.h"
  29. #include "fp4/pbuf.h"
  30. #include "fp4/cmdmacro.h"
  31. #include "ab.h"
  32. #include "glob.h"
  33. #endif
  34.  
  35. #if (defined(unix) && !defined(KINETICS))
  36. #include <sys/types.h>
  37. #include <netinet/in.h>
  38. #ifndef NULL
  39. #define NULL 0
  40. #endif
  41. #endif
  42.  
  43.  
  44. #include "asn1.h"
  45. #include "snmp.h"
  46. #include "snmp_impl.h"
  47. #include "mib.h"
  48. #include "inet.h"
  49. #include "snmp_vars.h"
  50. /*
  51.  *    Each variable name is placed in the variable table, without the terminating
  52.  * substring that determines the instance of the variable.  When a string is found that
  53.  * is lexicographicly preceded by the input string, the function for that entry is
  54.  * called to find the method of access of the instance of the named variable.  If
  55.  * that variable is not found, NULL is returned, and the search through the table
  56.  * continues (it should stop at the next entry).  If it is found, the function returns
  57.  * a character pointer and a length or a function pointer.  The former is the address
  58.  * of the operand, the latter is an access routine for the variable.
  59.  *
  60.  * u_char *
  61.  * findVar(name, length, exact, var_len, access_method)
  62.  * oid        *name;        IN/OUT - input name requested, output name found
  63.  * int        length;        IN/OUT - number of sub-ids in the in and out oid's
  64.  * int        exact;        IN - TRUE if an exact match was requested.
  65.  * int        len;        OUT - length of variable or 0 if function returned.
  66.  * int        access_method; OUT - 1 if function, 0 if char pointer.
  67.  *
  68.  * accessVar(rw, var, varLen)
  69.  * int        rw;        IN - request to READ or WRITE the variable
  70.  * u_char   *var;   IN/OUT - input or output buffer space
  71.  * int        *varLen;IN/OUT - input and output buffer len
  72.  */
  73.  
  74. struct variable {
  75.     oid            name[16];        /* object identifier of variable */
  76.     u_char        namelen;        /* length of above */
  77.     char        type;        /* type of variable, INTEGER or (octet) STRING */
  78.     u_char        magic;        /* passed to function as a hint */
  79.     u_short        acl;        /* access control list for variable */
  80.     u_char        *(*findVar)();  /* function that finds variable */
  81. };
  82.  
  83. char        version_descr[30] = "Kinetics FastPath4";
  84. oid        version_id[] = {1, 3, 6, 1, 4, 1, 3, 1, 1};
  85. int        version_id_len = sizeof(version_id);
  86. u_long        uptime;
  87. long        cfg_nnets = MAX_INTERFACES;
  88. long        long_return;
  89. u_char        return_buf[64];
  90.  
  91.  
  92. struct mib_ifEntry  mib_ifEntry_proto[MAX_INTERFACES] = {
  93.     {1, "Kinetics KFPS2 Ethernet", MIB_IFTYPE_ETHERNETCSMACD, 
  94.         1500, 10000000L, "", 
  95.     6, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
  96.     {2, "Kinetics KFPS2 Appletalk", MIB_IFTYPE_OTHER,
  97.         1500, 230000L, "", 
  98.     3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
  99. };
  100. struct mib_ifEntry mib_ifEntry[MAX_INTERFACES];
  101.  
  102. struct mib_ip mib_ip_proto = {
  103.     1, IPFRAGTTL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  104. };
  105. struct mib_ip mib_ip;
  106.  
  107. #define ROUTE_DEFAULT    0
  108. #define ROUTE_LOCAL    1
  109. struct mib_ipRouteEntry mib_ipRouteEntry_proto[2] = {
  110.     {0, 1, 1, -1, -1, -1, 0, MIB_IPROUTETYPE_REMOTE, MIB_IPROUTEPROTO_LOCAL, 0},    /* default route */
  111.     {0, 1, 0, -1, -1, -1, 0, MIB_IPROUTETYPE_DIRECT, MIB_IPROUTEPROTO_LOCAL, 0}        /* local route */
  112. };
  113. struct mib_ipRouteEntry mib_ipRouteEntry[2];
  114.  
  115. struct mib_udp mib_udp_proto = {
  116.     0, 0, 0, 0
  117. };
  118. struct mib_udp mib_udp;
  119.  
  120. long    mib_icmpInMsgs;
  121. long    mib_icmpOutMsgs;
  122. long    mib_icmpInErrors;    /* not checked in KIP */
  123. long    mib_icmpOutErrors;    /* not checked in KIP */
  124. long    mib_icmpInCount[ICMP_MAXTYPE + 1];
  125. long    mib_icmpOutCount[ICMP_MAXTYPE + 1];
  126.  
  127.  
  128. init_snmp(){
  129.     bcopy((char *)mib_ifEntry_proto, (char *)mib_ifEntry, sizeof(mib_ifEntry));
  130.     bcopy((char *)&mib_ip_proto, (char *)&mib_ip, sizeof(mib_ip));
  131.     bcopy((char *)mib_ipRouteEntry_proto, (char *)mib_ipRouteEntry, sizeof(mib_ipRouteEntry));
  132.     bcopy((char *)&mib_udp_proto, (char *)&mib_udp, sizeof(mib_udp));
  133. }
  134.  
  135. /*
  136.  * These are byte offsets into their structures.
  137.  * This really should be computed by the compiler, but the
  138.  * compiler I'm using doesn't want to do this.
  139.  */
  140. #define VERSION_DESCR    0
  141. #define VERSION_ID    32
  142. #define CFG_NNETS    48
  143. #define UPTIME        52
  144.  
  145. #define IFINDEX        0
  146. #define IFDESCR        4
  147. #define IFTYPE        36
  148. #define IFMTU        40
  149. #define IFSPEED        44
  150. #define IFPHYSADDRESS    48
  151. #define IFADMINSTATUS    60
  152. #define IFOPERSTATUS    64
  153. #define IFLASTCHANGE    68
  154. #define IFINOCTETS    72
  155. #define IFINUCASTPKTS    76
  156. #define    IFINNUCASTPKTS    80
  157. #define    IFINDISCARDS    84
  158. #define    IFINERRORS    88
  159. #define    IFINUNKNOWNPROTOS   92
  160. #define    IFOUTOCTETS    96
  161. #define    IFOUTUCASTPKTS    100
  162. #define    IFOUTNUCASTPKTS    104
  163. #define    IFOUTDISCARDS    108
  164. #define    IFOUTERRORS    112
  165. #define    IFOUTQLEN    116
  166.  
  167. #define ATIFINDEX    0
  168. #define ATPHYSADDRESS    4
  169. #define ATNETADDRESS    16
  170.  
  171. #define IPFORWARDING    0
  172. #define IPDEFAULTTTL    4
  173. #define IPINRECEIVES    8
  174. #define IPINHDRERRORS    12
  175. #define IPINADDRERRORS    16
  176. #define IPFORWDATAGRAMS    20
  177. #define IPINUNKNOWNPROTOS   24
  178. #define IPINDISCARDS    28
  179. #define IPINDELIVERS    32
  180. #define IPOUTREQUESTS    36
  181. #define IPOUTDISCARDS    40
  182. #define IPOUTNOROUTES    44
  183. #define IPREASMTIMEOUT    48
  184. #define IPREASMREQDS    52
  185. #define IPREASMOKS    56
  186. #define IPREASMFAILS    60
  187. #define IPFRAGOKS    64
  188. #define IPFRAGFAILS    68
  189. #define IPFRAGCREATES    72
  190.  
  191. #define IPADADDR    0
  192. #define IPADIFINDEX    4
  193. #define IPADNETMASK    8
  194. #define IPADBCASTADDR    12
  195.  
  196. #define IPROUTEDEST    0
  197. #define IPROUTEIFINDEX    4
  198. #define IPROUTEMETRIC1    8
  199. #define IPROUTEMETRIC2    12
  200. #define IPROUTEMETRIC3    16
  201. #define IPROUTEMETRIC4    20
  202. #define IPROUTENEXTHOP    24
  203. #define IPROUTETYPE    28
  204. #define IPROUTEPROTO    32
  205. #define IPROUTEAGE    36
  206.  
  207. #define    ICMPINMSGS        0
  208. #define    ICMPINERRORS        4
  209. #define    ICMPINDESTUNREACHS  8
  210. #define    ICMPINTIMEEXCDS        12
  211. #define    ICMPINPARMPROBS        16
  212. #define    ICMPINSRCQUENCHS    20
  213. #define    ICMPINREDIRECTS        24
  214. #define    ICMPINECHOS        28
  215. #define    ICMPINECHOREPS        32
  216. #define    ICMPINTIMESTAMPS    36
  217. #define    ICMPINTIMESTAMPREPS 40
  218. #define    ICMPINADDRMASKS        44
  219. #define    ICMPINADDRMASKREPS  48
  220. #define    ICMPOUTMSGS        52
  221. #define    ICMPOUTERRORS        56
  222. #define    ICMPOUTDESTUNREACHS 60
  223. #define    ICMPOUTTIMEEXCDS    64
  224. #define    ICMPOUTPARMPROBS    68
  225. #define    ICMPOUTSRCQUENCHS   72
  226. #define    ICMPOUTREDIRECTS    76
  227. #define    ICMPOUTECHOS        80
  228. #define    ICMPOUTECHOREPS        84
  229. #define    ICMPOUTTIMESTAMPS   88
  230. #define    ICMPOUTTIMESTAMPREPS    92
  231. #define    ICMPOUTADDRMASKS    96
  232. #define    ICMPOUTADDRMASKREPS 100
  233.  
  234. #define UDPINDATAGRAMS        0
  235. #define UDPNOPORTS        4
  236. #define    UDPINERRORS        8
  237. #define UDPOUTDATAGRAMS        12
  238.  
  239. struct variable        variables[] = {
  240.     /* these must be lexicographly ordered by the name field */
  241.     {{MIB, 1, 1, 0},        9, STRING,  VERSION_DESCR, RONLY, var_system },
  242.     {{MIB, 1, 2, 0},        9, OBJID,   VERSION_ID, RONLY, var_system },
  243.     {{MIB, 1, 3, 0},        9, TIMETICKS, UPTIME, RONLY, var_system },
  244.     {{MIB, 2, 1, 0},        9, INTEGER, CFG_NNETS, RONLY, var_system },
  245.     {{MIB, 2, 2, 1, 1, 0xFF},  11, INTEGER, IFINDEX, RONLY, var_ifEntry },
  246.     {{MIB, 2, 2, 1, 2, 0xFF},  11, STRING,  IFDESCR, RONLY, var_ifEntry },
  247.     {{MIB, 2, 2, 1, 3, 0xFF},  11, INTEGER, IFTYPE, RONLY, var_ifEntry },
  248.     {{MIB, 2, 2, 1, 4, 0xFF},  11, INTEGER, IFMTU, RONLY, var_ifEntry },
  249.     {{MIB, 2, 2, 1, 5, 0xFF},  11, GAUGE,   IFSPEED, RONLY, var_ifEntry },
  250.     {{MIB, 2, 2, 1, 6, 0xFF},  11, STRING,  IFPHYSADDRESS, RONLY, var_ifEntry },
  251.     {{MIB, 2, 2, 1, 7, 0xFF},  11, INTEGER, IFADMINSTATUS, RWRITE, var_ifEntry },
  252.     {{MIB, 2, 2, 1, 8, 0xFF},  11, INTEGER, IFOPERSTATUS, RONLY, var_ifEntry },
  253.     {{MIB, 2, 2, 1, 9, 0xFF},  11, TIMETICKS, IFLASTCHANGE, RONLY, var_ifEntry },
  254.     {{MIB, 2, 2, 1, 10, 0xFF}, 11, COUNTER, IFINOCTETS, RONLY, var_ifEntry },
  255.     {{MIB, 2, 2, 1, 11, 0xFF}, 11, COUNTER, IFINUCASTPKTS, RONLY, var_ifEntry },
  256.     {{MIB, 2, 2, 1, 12, 0xFF}, 11, COUNTER, IFINNUCASTPKTS, RONLY, var_ifEntry },
  257.     {{MIB, 2, 2, 1, 13, 0xFF}, 11, COUNTER, IFINDISCARDS, RONLY, var_ifEntry },
  258.     {{MIB, 2, 2, 1, 14, 0xFF}, 11, COUNTER, IFINERRORS, RONLY, var_ifEntry },
  259.     {{MIB, 2, 2, 1, 15, 0xFF}, 11, COUNTER, IFINUNKNOWNPROTOS, RONLY, var_ifEntry },
  260.     {{MIB, 2, 2, 1, 16, 0xFF}, 11, COUNTER, IFOUTOCTETS, RONLY, var_ifEntry },
  261.     {{MIB, 2, 2, 1, 17, 0xFF}, 11, COUNTER, IFOUTUCASTPKTS, RONLY, var_ifEntry },
  262.     {{MIB, 2, 2, 1, 18, 0xFF}, 11, COUNTER, IFOUTNUCASTPKTS, RONLY, var_ifEntry },
  263.     {{MIB, 2, 2, 1, 19, 0xFF}, 11, COUNTER, IFOUTDISCARDS, RONLY, var_ifEntry },
  264.     {{MIB, 2, 2, 1, 20, 0xFF}, 11, COUNTER, IFOUTERRORS, RONLY, var_ifEntry },
  265.     {{MIB, 2, 2, 1, 21, 0xFF}, 11, GAUGE,   IFOUTQLEN, RONLY, var_ifEntry },
  266.     {{MIB, 3, 1, 1, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, 16, INTEGER,    ATIFINDEX, RWRITE, var_atEntry }, 
  267.     {{MIB, 3, 1, 1, 2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, 16, STRING,        ATPHYSADDRESS, RWRITE, var_atEntry }, 
  268.     {{MIB, 3, 1, 1, 3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, 16, IPADDRESS,  ATNETADDRESS, RWRITE, var_atEntry },
  269.     {{MIB, 4, 1, 0},        9, INTEGER, IPFORWARDING, RONLY, var_ip },
  270.     {{MIB, 4, 2, 0},        9, INTEGER, IPDEFAULTTTL, RWRITE, var_ip },
  271.     {{MIB, 4, 3, 0},        9, COUNTER, IPINRECEIVES, RONLY, var_ip },
  272.     {{MIB, 4, 4, 0},        9, COUNTER, IPINHDRERRORS, RONLY, var_ip },
  273.     {{MIB, 4, 5, 0},        9, COUNTER, IPINADDRERRORS, RONLY, var_ip },
  274.     {{MIB, 4, 6, 0},        9, COUNTER, IPFORWDATAGRAMS, RONLY, var_ip },
  275.     {{MIB, 4, 7, 0},        9, COUNTER, IPINUNKNOWNPROTOS, RONLY, var_ip },
  276.     {{MIB, 4, 8, 0},        9, COUNTER, IPINDISCARDS, RONLY, var_ip },
  277.     {{MIB, 4, 9, 0},        9, COUNTER, IPINDELIVERS, RONLY, var_ip },
  278.     {{MIB, 4, 10, 0},        9, COUNTER, IPOUTREQUESTS, RONLY, var_ip },
  279.     {{MIB, 4, 11, 0},        9, COUNTER, IPOUTDISCARDS, RONLY, var_ip },
  280.     {{MIB, 4, 12, 0},        9, COUNTER, IPOUTNOROUTES, RONLY, var_ip },
  281.     {{MIB, 4, 13, 0},        9, INTEGER, IPREASMTIMEOUT, RONLY, var_ip },
  282.     {{MIB, 4, 14, 0},        9, COUNTER, IPREASMREQDS, RONLY, var_ip },
  283.     {{MIB, 4, 15, 0},        9, COUNTER, IPREASMOKS, RONLY, var_ip },
  284.     {{MIB, 4, 16, 0},        9, COUNTER, IPREASMFAILS, RONLY, var_ip },
  285.     {{MIB, 4, 17, 0},        9, COUNTER, IPFRAGOKS, RONLY, var_ip },
  286.     {{MIB, 4, 18, 0},        9, COUNTER, IPFRAGFAILS, RONLY, var_ip },
  287.     {{MIB, 4, 19, 0},        9, COUNTER, IPFRAGCREATES, RONLY, var_ip },
  288.     {{MIB, 4, 20, 1, 1, 0xFF, 0xFF, 0xFF, 0xFF}, 14, IPADDRESS, IPADADDR, RONLY, var_ipAddrEntry },
  289.     {{MIB, 4, 20, 1, 2, 0xFF, 0xFF, 0xFF, 0xFF}, 14, INTEGER,    IPADIFINDEX, RONLY, var_ipAddrEntry },
  290.     {{MIB, 4, 20, 1, 3, 0xFF, 0xFF, 0xFF, 0xFF}, 14, IPADDRESS, IPADNETMASK, RONLY, var_ipAddrEntry },
  291.     {{MIB, 4, 20, 1, 4, 0xFF, 0xFF, 0xFF, 0xFF}, 14, INTEGER,    IPADBCASTADDR, RONLY, var_ipAddrEntry },
  292.     {{MIB, 4, 21, 1, 1, 0xFF, 0xFF, 0xFF, 0xFF}, 14, IPADDRESS, IPROUTEDEST, RWRITE, var_ipRouteEntry },
  293.     {{MIB, 4, 21, 1, 2, 0xFF, 0xFF, 0xFF, 0xFF}, 14, INTEGER,    IPROUTEIFINDEX, RWRITE, var_ipRouteEntry },
  294.     {{MIB, 4, 21, 1, 3, 0xFF, 0xFF, 0xFF, 0xFF}, 14, INTEGER,    IPROUTEMETRIC1, RWRITE, var_ipRouteEntry },
  295.     {{MIB, 4, 21, 1, 4, 0xFF, 0xFF, 0xFF, 0xFF}, 14, INTEGER,    IPROUTEMETRIC2, RWRITE, var_ipRouteEntry },
  296.     {{MIB, 4, 21, 1, 5, 0xFF, 0xFF, 0xFF, 0xFF}, 14, INTEGER,    IPROUTEMETRIC3, RWRITE, var_ipRouteEntry },
  297.     {{MIB, 4, 21, 1, 6, 0xFF, 0xFF, 0xFF, 0xFF}, 14, INTEGER,    IPROUTEMETRIC4, RWRITE, var_ipRouteEntry },
  298.     {{MIB, 4, 21, 1, 7, 0xFF, 0xFF, 0xFF, 0xFF}, 14, IPADDRESS, IPROUTENEXTHOP, RWRITE, var_ipRouteEntry },
  299.     {{MIB, 4, 21, 1, 8, 0xFF, 0xFF, 0xFF, 0xFF}, 14, INTEGER,    IPROUTETYPE, RWRITE, var_ipRouteEntry },
  300.     {{MIB, 4, 21, 1, 9, 0xFF, 0xFF, 0xFF, 0xFF}, 14, INTEGER,    IPROUTEPROTO, RONLY, var_ipRouteEntry },
  301.     {{MIB, 4, 21, 1, 10, 0xFF, 0xFF, 0xFF, 0xFF}, 14, INTEGER,    IPROUTEAGE, RWRITE, var_ipRouteEntry },
  302.     {{MIB, 5, 1, 0},        9, COUNTER, ICMPINMSGS, RONLY, var_icmp },
  303.     {{MIB, 5, 2, 0},        9, COUNTER, ICMPINERRORS, RONLY, var_icmp },
  304.     {{MIB, 5, 3, 0},        9, COUNTER, ICMPINDESTUNREACHS, RONLY, var_icmp },
  305.     {{MIB, 5, 4, 0},        9, COUNTER, ICMPINTIMEEXCDS, RONLY, var_icmp },
  306.     {{MIB, 5, 5, 0},        9, COUNTER, ICMPINPARMPROBS, RONLY, var_icmp },
  307.     {{MIB, 5, 6, 0},        9, COUNTER, ICMPINSRCQUENCHS, RONLY, var_icmp },
  308.     {{MIB, 5, 7, 0},        9, COUNTER, ICMPINREDIRECTS, RONLY, var_icmp },
  309.     {{MIB, 5, 8, 0},        9, COUNTER, ICMPINECHOS, RONLY, var_icmp },
  310.     {{MIB, 5, 9, 0},        9, COUNTER, ICMPINECHOREPS, RONLY, var_icmp },
  311.     {{MIB, 5, 10, 0},        9, COUNTER, ICMPINTIMESTAMPS, RONLY, var_icmp },
  312.     {{MIB, 5, 11, 0},        9, COUNTER, ICMPINTIMESTAMPREPS, RONLY, var_icmp },
  313.     {{MIB, 5, 12, 0},        9, COUNTER, ICMPINADDRMASKS, RONLY, var_icmp },
  314.     {{MIB, 5, 13, 0},        9, COUNTER, ICMPINADDRMASKREPS, RONLY, var_icmp },
  315.     {{MIB, 5, 14, 0},        9, COUNTER, ICMPOUTMSGS, RONLY, var_icmp },
  316.     {{MIB, 5, 15, 0},        9, COUNTER, ICMPOUTERRORS, RONLY, var_icmp },
  317.     {{MIB, 5, 16, 0},        9, COUNTER, ICMPOUTDESTUNREACHS, RONLY, var_icmp },
  318.     {{MIB, 5, 17, 0},        9, COUNTER, ICMPOUTTIMEEXCDS, RONLY, var_icmp },
  319.     {{MIB, 5, 18, 0},        9, COUNTER, ICMPOUTPARMPROBS, RONLY, var_icmp },
  320.     {{MIB, 5, 19, 0},        9, COUNTER, ICMPOUTSRCQUENCHS, RONLY, var_icmp },
  321.     {{MIB, 5, 20, 0},        9, COUNTER, ICMPOUTREDIRECTS, RONLY, var_icmp },
  322.     {{MIB, 5, 21, 0},        9, COUNTER, ICMPOUTECHOS, RONLY, var_icmp },
  323.     {{MIB, 5, 22, 0},        9, COUNTER, ICMPOUTECHOREPS, RONLY, var_icmp },
  324.     {{MIB, 5, 23, 0},        9, COUNTER, ICMPOUTTIMESTAMPS, RONLY, var_icmp },
  325.     {{MIB, 5, 24, 0},        9, COUNTER, ICMPOUTTIMESTAMPREPS, RONLY, var_icmp },
  326.     {{MIB, 5, 25, 0},        9, COUNTER, ICMPOUTADDRMASKS, RONLY, var_icmp },
  327.     {{MIB, 5, 26, 0},        9, COUNTER, ICMPOUTADDRMASKREPS, RONLY, var_icmp },
  328.     {{MIB, 7, 1, 0},        9, COUNTER, UDPINDATAGRAMS, RONLY, var_udp }, 
  329.     {{MIB, 7, 2, 0},        9, COUNTER, UDPNOPORTS, RONLY, var_udp },
  330.     {{MIB, 7, 3, 0},        9, COUNTER, UDPINERRORS, RONLY, var_udp }, 
  331.     {{MIB, 7, 4, 0},        9, COUNTER, UDPOUTDATAGRAMS, RONLY, var_udp }
  332. };
  333.  
  334.  
  335.  
  336.  
  337. /*
  338.  * getStatPtr - return a pointer to the named variable, as well as it's
  339.  * type, length, and access control list.
  340.  *
  341.  * If an exact match for the variable name exists, it is returned.  If not,
  342.  * and exact is false, the next variable lexicographically after the
  343.  * requested one is returned.
  344.  *
  345.  * If no appropriate variable can be found, NULL is returned.
  346.  */
  347. u_char  *
  348. getStatPtr(name, namelen, type, len, acl, exact, access_method)
  349.     oid        *name;        /* IN - name of var, OUT - name matched */
  350.     int        *namelen;   /* IN -number of sub-ids in name, OUT - subid-is in matched name */
  351.     u_char    *type;        /* OUT - type of matched variable */
  352.     int        *len;        /* OUT - length of matched variable */
  353.     u_short    *acl;        /* OUT - access control list */
  354.     int        exact;        /* IN - TRUE if exact match wanted */
  355.     int        *access_method; /* OUT - 1 if function, 0 if char * */
  356. {
  357.  
  358.     register struct variable    *vp;
  359.  
  360.     register int    x;
  361.     register u_char    *access;
  362.     int            result;
  363.  
  364.     for(x = 0, vp = variables; x < sizeof(variables)/sizeof(struct variable); vp++, x++){
  365.     /*
  366.      * compare should be expanded inline.
  367.      */
  368.     result = compare(name, *namelen, vp->name, (int)vp->namelen);
  369.     if ((result < 0) || (exact && (result == 0))){
  370.         access = (*(vp->findVar))(vp, name, namelen, exact, len, access_method);
  371.         if (access != NULL)
  372.         break;
  373.     }
  374.     }
  375.     if (x == sizeof(variables)/sizeof(struct variable))
  376.     return NULL;
  377.  
  378.     /* vp now points to the approprate struct */
  379.     *type = vp->type;
  380.     *acl = vp->acl;
  381.     return access;
  382. }
  383.  
  384.  
  385.  
  386. int
  387. compare(name1, len1, name2, len2)
  388.     register oid        *name1, *name2;
  389.     register int        len1, len2;
  390. {
  391.     register int    len;
  392.  
  393.     /* len = minimum of len1 and len2 */
  394.     if (len1 < len2)
  395.     len = len1;
  396.     else
  397.     len = len2;
  398.     /* find first non-matching byte */
  399.     while(len-- > 0){
  400.     if (*name1 < *name2)
  401.         return -1;
  402.     if (*name2++ < *name1++)
  403.         return 1;
  404.     }
  405.     /* bytes match up to length of shorter string */
  406.     if (len1 < len2)
  407.     return -1;  /* name1 shorter, so it is "less" */
  408.     if (len2 < len1)
  409.     return 1;
  410.     return 0;    /* both strings are equal */
  411. }
  412.  
  413.  
  414. u_char *
  415. var_system(vp, name, length, exact, var_len, access_method)
  416.     register struct variable *vp;   /* IN - pointer to variable entry that points here */
  417.     register oid    *name;        /* IN/OUT - input name requested, output name found */
  418.     register int    *length;    /* IN/OUT - length of input and output oid's */
  419.     int            exact;        /* IN - TRUE if an exact match was requested. */
  420.     int            *var_len;   /* OUT - length of variable or 0 if function returned. */
  421.     int            *access_method;    /* OUT - 1 if function, 0 if char pointer. */
  422. {
  423.     if (exact && (compare(name, *length, vp->name, (int)vp->namelen) != 0))
  424.     return NULL;
  425.     bcopy((char *)vp->name, (char *)name, (int)vp->namelen * sizeof(oid));
  426.     *length = vp->namelen;
  427.     *access_method = 0;
  428.     *var_len = sizeof(long);    /* default length */
  429.     switch (vp->magic){
  430.     case VERSION_DESCR:
  431.         *var_len = strlen(version_descr);
  432.         return (u_char *)version_descr;
  433.     case VERSION_ID:
  434.         *var_len = sizeof(version_id);
  435.         return (u_char *)version_id;
  436.     case CFG_NNETS:
  437.         return (u_char *)&cfg_nnets;
  438.     case UPTIME:
  439.         return (u_char *)&uptime;
  440.     default:
  441.         ERROR("");
  442.     }
  443.     return NULL;
  444. }
  445.  
  446.  
  447. u_char *
  448. var_ifEntry(vp, name, length, exact, var_len, access_method)
  449.     register struct variable *vp;   /* IN - pointer to variable entry that points here */
  450.     register oid    *name;        /* IN/OUT - input name requested, output name found */
  451.     register int    *length;    /* IN/OUT - length of input and output oid's */
  452.     int            exact;        /* IN - TRUE if an exact match was requested. */
  453.     int            *var_len;   /* OUT - length of variable or 0 if function returned. */
  454.     int            *access_method; /* OUT - 1 if function, 0 if char pointer. */
  455. {
  456.     oid            newname[MAX_NAME_LEN];
  457.     register int    interface;
  458.     register struct mib_ifEntry    *ifp;
  459.     extern struct conf    conf;
  460.     int            result;
  461.  
  462.     bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
  463.     /* find "next" interface */
  464.     for(interface = 1; interface <= MAX_INTERFACES; interface++){
  465.     newname[10] = (oid)interface;
  466.     result = compare(name, *length, newname, (int)vp->namelen);
  467.     if ((exact && (result == 0)) || (!exact && (result < 0)))
  468.         break;
  469.     }
  470.     if (interface > MAX_INTERFACES)
  471.     return NULL;
  472.     interface--; /* translate into internal index of interfaces */
  473.     bcopy((char *)newname, (char *)name, (int)vp->namelen * sizeof(oid));
  474.     *length = vp->namelen;
  475.     *access_method = 0;
  476.     *var_len = sizeof(long);
  477.  
  478.     ifp = &mib_ifEntry[interface];
  479.     switch (vp->magic){
  480.         case IFDESCR:
  481.         *var_len = strlen(ifp->ifDescr);
  482.         return (u_char *)ifp->ifDescr;
  483.     case IFPHYSADDRESS:
  484.         *var_len = ifp->PhysAddrLen;
  485.         if (interface == 0)
  486.             return (u_char *)ifie.if_haddr;
  487.         else {
  488.         /*
  489.          * As far as IP is concerned, the "physical" address includes the Appletalk
  490.          * network address as well as node number.
  491.          */
  492.         return_buf[0] = ((u_char *)&conf.atneta)[0];
  493.         return_buf[1] = ((u_char *)&conf.atneta)[1];
  494.         return_buf[2] = ifab.if_dnode;
  495.             return (u_char *)return_buf;
  496.         }
  497.     case IFOUTQLEN:
  498. #ifdef notdef
  499.         if (interface == 0)
  500.         long_return = sendq->pq_len;
  501.         else
  502.         long_return = 0;    /* There is no appletalk transmit queue */
  503. #else
  504.         long_return = 0;
  505. #endif
  506.         return (u_char *)&long_return;
  507.     default:
  508.         return (u_char *)(((char *)ifp) + vp->magic);
  509.     }
  510. }
  511.  
  512. /* 
  513.  * from arp.c:
  514.  * There is no arp.h, so this must be recreated here.
  515.  */
  516. #define    ARPHLNMAX    6    /* largest arp_hln value needed */
  517. #define    ARPPLN        4    /* length of protocol address (IP) */
  518. struct    arptab {
  519.     iaddr_t at_iaddr;        /* internet address */
  520.     u_char    at_haddr[ARPHLNMAX];    /* hardware address */
  521.     u_char    at_timer;        /* minutes since last reference */
  522.     u_char    at_flags;        /* flags */
  523.     struct    pbuf *at_hold;        /* last packet until resolved/timeout */
  524. };
  525. /* at_flags field values */
  526. #define    ATF_INUSE    1        /* entry in use */
  527. #define ATF_COM        2        /* completed entry (haddr valid) */
  528.  
  529. #define    ARPTAB_BSIZ    5        /* bucket size */
  530. #define    ARPTAB_NB    11        /* number of buckets */
  531. #define    ARPTAB_SIZE    (ARPTAB_BSIZ * ARPTAB_NB)
  532.  
  533.  
  534. u_char *
  535. var_atEntry(vp, name, length, exact, var_len, access_method)
  536.     register struct variable *vp;    /* IN - pointer to variable entry that points here */
  537.     register oid        *name;    /* IN/OUT - input name requested, output name found */
  538.     register int        *length;    /* IN/OUT - length of input and output oid's */
  539.     int                exact;    /* IN - TRUE if an exact match was requested. */
  540.     int                *var_len;    /* OUT - length of variable or 0 if function returned. */
  541.     int                *access_method; /* OUT - 1 if function, 0 if char pointer. */
  542. {
  543.     /*
  544.      * object identifier is of form:
  545.      * 1.3.6.1.2.1.3.1.1.1.interface.1.A.B.C.D,  where A.B.C.D is IP address.
  546.      * Interface is at offset 10,
  547.      * IPADDR starts at offset 12.
  548.      */
  549.     oid                lowest[16];
  550.     oid                current[16];
  551.     register struct arptab  *arp;
  552.     struct arptab        *lowarp = 0;
  553.     extern struct arptab    arptab[];
  554.     register struct ipdad   *ipdp;
  555.     struct ipdad        *lowipdp = 0;
  556.     extern struct ipdad        ipdad[];
  557.     long            ipaddr;
  558.     int                addrlen;
  559.     extern struct conf        conf;
  560.     register u_char        *cp;
  561.     register oid        *op;
  562.     register int        count;
  563.  
  564.     /* fill in object part of name for current (less sizeof instance part) */
  565.     bcopy((char *)vp->name, (char *)current, (int)(vp->namelen - 6) * sizeof(oid));
  566.     for(arp = arptab; arp < arptab + ARPTAB_SIZE; arp++){
  567.     if (!(arp->at_flags & ATF_COM))    /* if this entry isn't valid */
  568.         continue;
  569.     /* create new object id */
  570.     current[10] = 1;    /* ifIndex == 1 (ethernet) */
  571.     current[11] = 1;
  572.     cp = (u_char *)&(arp->at_iaddr);
  573.     op = current + 12;
  574.     for(count = 4; count > 0; count--)
  575.         *op++ = *cp++;
  576.     if (exact){
  577.         if (compare(current, 16, name, *length) == 0){
  578.         bcopy((char *)current, (char *)lowest, 16 * sizeof(oid));
  579.         lowarp = arp;
  580.         break;    /* no need to search further */
  581.         }
  582.     } else {
  583.         if ((compare(current, 16, name, *length) > 0) && (!lowarp || (compare(current, 16, lowest, 16) < 0))){
  584.         /*
  585.          * if new one is greater than input and closer to input than
  586.          * previous lowest, save this one as the "next" one.
  587.          */
  588.         bcopy((char *)current, (char *)lowest, 16 * sizeof(oid));
  589.         lowarp = arp;
  590.         }
  591.     }
  592.     }
  593.     ipaddr = conf.ipaddr + conf.ipstatic + 1;
  594.     for(ipdp = ipdad; ipdp < ipdad + NIPDAD; ipdp++, ipaddr++){
  595.     if (ipdp->timer == 0)    /* if this entry is unused, continue */
  596.         continue;
  597.     /* create new object id */
  598.     current[10] = 2;    /* ifIndex == 2 (appletalk) */
  599.     current[11] = 1;
  600.     cp = (u_char *)&ipaddr;
  601.     op = current + 12;
  602.     for(count = 4; count > 0; count--)
  603.         *op++ = *cp++;
  604.     if (exact){
  605.         if (compare(current, 16, name, *length) == 0){
  606.         bcopy((char *)current, (char *)lowest, 16 * sizeof(oid));
  607.         lowipdp = ipdp;
  608.         lowarp = 0;
  609.         break;    /* no need to search further */
  610.         }
  611.     } else {
  612.         if ((compare(current, 16, name, *length) > 0) && ((!lowarp && !lowipdp) || (compare(current, 16, lowest, 16) < 0))){
  613.         /*
  614.          * if new one is greater than input and closer to input than
  615.          * previous lowest, save this one as the "next" one.
  616.          */
  617.         bcopy((char *)current, (char *)lowest, 16 * sizeof(oid));
  618.         lowipdp = ipdp;
  619.         /* ipdad entry is lower, so invalidate arp entry */
  620.         lowarp = 0;
  621.         }
  622.     }
  623.     }
  624.     if (lowarp != 0){    /* arp entry was lowest */
  625.     addrlen = 6;
  626.     bcopy((char *)lowarp->at_haddr, (char *)return_buf, 6);
  627.     } else if (lowipdp != 0) {
  628.     addrlen = 3;
  629.     /*
  630.      * As far as IP is concerned, the "physical" address includes the Appletalk
  631.      * network address as well as node number.
  632.      */
  633.     return_buf[0] = ((u_char *)&lowipdp->net)[0];
  634.     return_buf[1] = ((u_char *)&lowipdp->net)[1];
  635.     return_buf[2] = lowipdp->node;
  636.     } else
  637.     return NULL;    /* no match */
  638.     bcopy((char *)lowest, (char *)name, 16 * sizeof(oid));
  639.     *length = 16;
  640.     *access_method = 0;
  641.     switch(vp->magic){
  642.     case ATIFINDEX:
  643.         *var_len = sizeof long_return;
  644.         long_return = lowest[10];
  645.         return (u_char *)&long_return;
  646.     case ATPHYSADDRESS:
  647.         *var_len = addrlen;
  648.         return (u_char *)return_buf;
  649.     case ATNETADDRESS:
  650.         *var_len = sizeof long_return;
  651.         cp = (u_char *)&long_return;
  652.         op = lowest + 12;
  653.         for(count = 4; count > 0; count--)
  654.         *cp++ = *op++;
  655.         return (u_char *)&long_return;
  656.     default:
  657.         ERROR("");
  658.    }
  659.    return NULL;
  660. }
  661.  
  662. u_char *
  663. var_ip(vp, name, length, exact, var_len, access_method)
  664.     register struct variable *vp;   /* IN - pointer to variable entry that points here */
  665.     oid        *name;        /* IN/OUT - input name requested, output name found */
  666.     int        *length;        /* IN/OUT - length of input and output oid's */
  667.     int        exact;        /* IN - TRUE if an exact match was requested. */
  668.     int        *var_len;        /* OUT - length of variable or 0 if function returned. */
  669.     int        *access_method; /* OUT - 1 if function, 0 if char pointer. */
  670. {
  671.     if (exact && (compare(name, *length, vp->name, (int)vp->namelen) != 0))
  672.     return NULL;
  673.     bcopy((char *)vp->name, (char *)name, (int)vp->namelen * sizeof(oid));
  674.     *length = vp->namelen;
  675.     *access_method = 0;
  676.     *var_len = sizeof(long);
  677.     return ((u_char *)&mib_ip) + vp->magic;
  678. }
  679.  
  680. u_char *
  681. var_ipRouteEntry(vp, name, length, exact, var_len, access_method)
  682.     register struct variable *vp;   /* IN - pointer to variable entry that points here */
  683.     register oid        *name;        /* IN/OUT - input name requested, output name found */
  684.     register int    *length;    /* IN/OUT - length of input and output strings */
  685.     int            exact;        /* IN - TRUE if an exact match was requested. */
  686.     int            *var_len;   /* OUT - length of variable or 0 if function returned. */
  687.     int            *access_method; /* OUT - 1 if function, 0 if char pointer. */
  688. {
  689.     oid                newname[MAX_NAME_LEN];
  690.     register int        entry;
  691.     register struct mib_ipRouteEntry    *routep;
  692.     int                result;
  693.     register int        count;
  694.     register u_char        *cp;
  695.     register oid        *op;
  696.     extern struct conf        conf;
  697.  
  698.     /* set up a routing table to search. All other values are set at startup. */
  699.     routep = mib_ipRouteEntry;
  700.     routep[ROUTE_DEFAULT].ipRouteDest = 0;
  701.     routep[ROUTE_DEFAULT].ipRouteNextHop = conf.iproutedef;
  702.     routep[ROUTE_LOCAL].ipRouteDest = ipnetpart(conf.ipaddr);
  703.     routep[ROUTE_LOCAL].ipRouteNextHop = conf.ipaddr;
  704.  
  705.     bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
  706.     /* find "next" route */
  707.     for(entry = 0; entry < ROUTE_ENTRIES; entry++){
  708.     cp = (u_char *)&routep->ipRouteDest;
  709.     op = newname + 10;
  710.     for(count = 4; count > 0; count--)
  711.         *op++ = *cp++;
  712.     result = compare(name, *length, newname, (int)vp->namelen);
  713.     if ((exact && (result == 0)) || (!exact && (result < 0)))
  714.         break;
  715.     routep++;
  716.     }
  717.     if (entry >= ROUTE_ENTRIES)
  718.     return NULL;
  719.     bcopy((char *)newname, (char *)name, (int)vp->namelen * sizeof(oid));
  720.     *length = vp->namelen;
  721.     *access_method = 0;
  722.     *var_len = sizeof(long);
  723.  
  724.     routep = &mib_ipRouteEntry[entry];
  725.     switch (vp->magic){
  726.     case IPROUTENEXTHOP:
  727.         if (entry == ROUTE_DEFAULT)
  728.         return (u_char *)&conf.iproutedef;
  729.         else
  730.         return (u_char *)&conf.ipaddr;
  731.     default:
  732.         return (u_char *)(((u_char *)routep) + vp->magic);
  733.     }
  734. }
  735.  
  736. u_char *
  737. var_ipAddrEntry(vp, name, length, exact, var_len, access_method)
  738.     register struct variable *vp;    /* IN - pointer to variable entry that points here */
  739.     register oid    *name;        /* IN/OUT - input name requested, output name found */
  740.     register int    *length;    /* IN/OUT - length of input and output oid's */
  741.     int            exact;        /* IN - TRUE if an exact match was requested. */
  742.     int            *var_len;   /* OUT - length of variable or 0 if function returned. */
  743.     int            *access_method; /* OUT - 1 if function, 0 if char pointer. */
  744. {
  745.     oid            newname[14];
  746.     int            result;
  747.     extern struct conf    conf;
  748.     register int    count;
  749.     register u_char *cp;
  750.     register oid    *op;
  751.  
  752.     bcopy((char *)vp->name, (char *)newname, (int)vp->namelen * sizeof(oid));
  753.     /* now find "next" ipaddr */
  754.     /*
  755.      * foreach ipaddress entry, cobble up newname with its IP address,
  756.      * by copying the ipaddress into the 10 - 13't subid's
  757.      * then compare with name.  If greater than name and less than lowest,
  758.      * save as new lowest.
  759.      * Having said all that, I'm now going to cheat because I only have one
  760.      * IP address (on both interfaces).
  761.      */
  762.     cp = (u_char *)&conf.ipaddr;
  763.     op = newname + 10;
  764.     for(count = sizeof(conf.ipaddr); count > 0; count--)
  765.     *op++ = *cp++;
  766.     result = compare(name, *length, newname, (int)vp->namelen);
  767.     if ((exact && (result != 0)) || (!exact && (result >= 0)))
  768.     return NULL;    /* no match */
  769.     bcopy((char *)newname, (char *)name, (int)vp->namelen * sizeof(oid));
  770.     *length = vp->namelen;
  771.     *access_method = 0;
  772.     *var_len = sizeof(long);
  773.  
  774.     switch (vp->magic){
  775.         case IPADADDR:
  776.         return (u_char *)&conf.ipaddr;
  777.         case IPADIFINDEX:
  778.         /*
  779.          * Always return ethernet interface. SNMP
  780.          * has no access method to access instances
  781.          * on different interfaces with same IP address.
  782.          */
  783.         long_return = 1;
  784.         return (u_char *)&long_return;
  785.     case IPADNETMASK:
  786.         long_return = (IN_CLASSA(conf.ipaddr) ? IN_CLASSA_NET :
  787.             (IN_CLASSB(conf.ipaddr) ? IN_CLASSB_NET : IN_CLASSC_NET));
  788.         return (u_char *)&long_return;
  789.     case IPADBCASTADDR:
  790.         long_return = conf.ipbroad & 1;
  791.         return (u_char *)&long_return;
  792.     default:
  793.         ERROR("");
  794.     }
  795.     return NULL;
  796. }
  797.  
  798.  
  799. u_char *
  800. var_icmp(vp, name, length, exact, var_len, access_method)
  801.     register struct variable *vp;    /* IN - pointer to variable entry that points here */
  802.     oid        *name;        /* IN/OUT - input name requested, output name found */
  803.     int        *length;        /* IN/OUT - length of input and output oid's */
  804.     int        exact;        /* IN - TRUE if an exact match was requested. */
  805.     int        *var_len;        /* OUT - length of variable or 0 if function returned. */
  806.     int        *access_method; /* OUT - 1 if function, 0 if char pointer. */
  807. {
  808.     if (exact && (compare(name, *length, vp->name, (int)vp->namelen) != 0))
  809.     return NULL;
  810.     bcopy((char *)vp->name, (char *)name, (int)vp->namelen * sizeof(oid));
  811.     *length = vp->namelen;
  812.     *access_method = 0;
  813.     *var_len = sizeof(long); /* all following variables are sizeof long */
  814.     switch (vp->magic){
  815.     case ICMPINMSGS:
  816.         return (u_char *)&mib_icmpInMsgs;
  817.     case ICMPINERRORS:
  818.         return (u_char *)&mib_icmpInErrors;
  819.     case ICMPINDESTUNREACHS:
  820.         return (u_char *)&mib_icmpInCount[3];
  821.     case ICMPINTIMEEXCDS:
  822.         return (u_char *)&mib_icmpInCount[11];
  823.     case ICMPINPARMPROBS:
  824.         return (u_char *)&mib_icmpInCount[12];
  825.     case ICMPINSRCQUENCHS:
  826.         return (u_char *)&mib_icmpInCount[4];
  827.     case ICMPINREDIRECTS:
  828.         return (u_char *)&mib_icmpInCount[5];
  829.     case ICMPINECHOS:
  830.         return (u_char *)&mib_icmpInCount[8];
  831.     case ICMPINECHOREPS:
  832.         return (u_char *)&mib_icmpInCount[0];
  833.     case ICMPINTIMESTAMPS:
  834.         return (u_char *)&mib_icmpInCount[13];
  835.     case ICMPINTIMESTAMPREPS:
  836.         return (u_char *)&mib_icmpInCount[14];
  837.     case ICMPINADDRMASKS:
  838.         return (u_char *)&mib_icmpInCount[17];
  839.     case ICMPINADDRMASKREPS:
  840.         return (u_char *)&mib_icmpInCount[18];
  841.     case ICMPOUTMSGS:
  842.         return (u_char *)&mib_icmpOutMsgs;
  843.     case ICMPOUTERRORS:
  844.         return (u_char *)&mib_icmpOutErrors;
  845.     case ICMPOUTDESTUNREACHS:
  846.         return (u_char *)&mib_icmpOutCount[3];
  847.     case ICMPOUTTIMEEXCDS:
  848.         return (u_char *)&mib_icmpOutCount[11];
  849.     case ICMPOUTPARMPROBS:
  850.         return (u_char *)&mib_icmpOutCount[12];
  851.     case ICMPOUTSRCQUENCHS:
  852.         return (u_char *)&mib_icmpOutCount[4];
  853.     case ICMPOUTREDIRECTS:
  854.         return (u_char *)&mib_icmpOutCount[5];
  855.     case ICMPOUTECHOS:
  856.         return (u_char *)&mib_icmpOutCount[8];
  857.     case ICMPOUTECHOREPS:
  858.         return (u_char *)&mib_icmpOutCount[0];
  859.     case ICMPOUTTIMESTAMPS:
  860.         return (u_char *)&mib_icmpOutCount[13];
  861.     case ICMPOUTTIMESTAMPREPS:
  862.         return (u_char *)&mib_icmpOutCount[14];
  863.     case ICMPOUTADDRMASKS:
  864.         return (u_char *)&mib_icmpOutCount[17];
  865.     case ICMPOUTADDRMASKREPS:
  866.         return (u_char *)&mib_icmpOutCount[18];
  867.     default:
  868.         ERROR("");
  869.     }
  870.     return NULL;
  871. }
  872.  
  873.  
  874. u_char *
  875. var_udp(vp, name, length, exact, var_len, access_method)
  876.     register struct variable *vp;    /* IN - pointer to variable entry that points here */
  877.     oid        *name;        /* IN/OUT - input name requested, output name found */
  878.     int        *length;        /* IN/OUT - length of input and output oid's */
  879.     int        exact;        /* IN - TRUE if an exact match was requested. */
  880.     int        *var_len;        /* OUT - length of variable or 0 if function returned. */
  881.     int        *access_method; /* OUT - 1 if function, 0 if char pointer. */
  882. {
  883.     if (exact && (compare(name, *length, vp->name, (int)vp->namelen) != 0))
  884.     return NULL;
  885.     bcopy((char *)vp->name, (char *)name, (int)vp->namelen * sizeof(oid));
  886.     *length = vp->namelen;
  887.     *access_method = 0;
  888.     *var_len = sizeof(long);
  889.     return ((u_char *)&mib_udp) + vp->magic;
  890. }
  891.